// 
//  Copyright © 2009 Jiří Zárevúcky <zarevucky.jiri@gmail.com>
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as
//  published by the Free Software Foundation, either version 3 of the
//  License, or (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Affero General Public License for more details.
// 
//  You should have received a copy of the GNU Affero General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// 

using System;

using Galaxium.Protocol.Xmpp.Library.Xml;
using Galaxium.Protocol.Xmpp.Library.Core;

namespace Galaxium.Protocol.Xmpp.Library.Extensions
{
	public class SoftwareVersion
	{
		public string Name { get; private set; }
		public string Version { get; private set; }
		public string OperatingSystem { get; private set; }
		
		public SoftwareVersion (string name, string version, string os)
		{
			if (name == null)
				throw new ArgumentNullException ("name");
			if (version == null)
				throw new ArgumentNullException ("version");
			
			Name = name;
			Version = version;
			OperatingSystem = os;
		}
		
		public SoftwareVersion (Element elm)
		{
			if (elm.Name != "query" || elm.Namespace != Namespaces.Version)
				throw new ArgumentException ();
			
			Name = elm.GetTextChild ("name", null);
			Version = elm.GetTextChild ("version", null);
			OperatingSystem = elm.GetTextChild ("os", null);
		}
		
		public Element ToXml ()
		{
			var query = new Element ("query", Namespaces.Version);
			query.AppendTextChild ("name", null, Name);
			query.AppendTextChild ("version", null, Version);
			if (OperatingSystem != null)
				query.AppendTextChild ("os", null, OperatingSystem);
			return query;
		}
		
		public static void AttachHandler (Client client, SoftwareVersion version)
		{
			client.DefineGetQueryHandler (Namespaces.Version, (Iq request) => {
				var response = request.Response ();
				response.AppendChild (version.ToXml ());
				client.Send (response);
			});
			client.RegisterFeature (Namespaces.Version);
		}
		
		public static void Get (Client client, JabberID jid,
		                        Action<SoftwareVersion> handler,
		                        Action<StanzaError> error_handler)
		{
			var request = new Iq (IqType.Get, Namespaces.Version);
			request.To = jid;
			client.SendQuery (request, (Iq result) => {
				if (result == null)
					error_handler (null);
				else if (result.IsError)
					error_handler (result.Error);
				else
					handler (new SoftwareVersion (result.Query));
			});
		}
		
		public static SoftwareVersion Get (Client client, JabberID jid)
		{
			var request = new Iq (IqType.Get, Namespaces.Version);
			request.To = jid;
			var result = client.SendQuery (request, 30000);
			return new SoftwareVersion (result.Query);
		}
	}
}
